package cn.wen.javax.servlet.http;

import java.io.UnsupportedEncodingException;
import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import cn.wen.bases.framework.spring.UtilsOfSpring;
import cn.wen.bases.framework.struts.UtilsOfStruts;
import cn.wen.java.nio.Encoder;

/**
 * Title：请求相关
 * <p>
 * Description：辅助工具。
 * <p>
 * Copyright：Copyright (c) 2010-2012
 * 
 * @author <a href="mailto:ct_wen@qq.com">ctwen</a>, 温承瑭
 * @version Revision：1.0 Date：2011/11/18 Description：初完成。
 *          <p>
 *          Revision：1.1 Date：2012/5/15 Description：新增getFullPath方法，重载getIpAddress方法（基于当前请求）。
 *          <p>
 */
public final class UtilsOfRequest {
    
    private static final Logger log = Logger.getLogger(UtilsOfRequest.class);

    /**
     * <pre>
     * 获取（当前）HttpServletRequest
     * 
     * PS：该方法需要Struts2（优先）、Spring支持。
     * <pre>
     * 
     * @return HttpServletRequest
     */
    public static HttpServletRequest getRequest() {
	HttpServletRequest request = null;
	try {
	    request = UtilsOfStruts.getHttpServletRequest();
	}
	catch (Exception e) { 
	    log.info(e.getMessage());
	}
	if (null == request) request = UtilsOfSpring.getHttpServletRequest();
	return request;
    }

    /**
     * 请求编码转换。
     * 
     * @param request HttpServletRequest对象
     * @param oldEncoding 原始编码
     * @param dtsEncoding 新编码
     * @throws UnsupportedEncodingException
     */
    public static void convertEncode(HttpServletRequest request, String oldEncoding, String dtsEncoding)
	    throws UnsupportedEncodingException {
	Enumeration<?> paramNames = request.getParameterNames();

	while (paramNames.hasMoreElements()) {
	    String paramName = (String) paramNames.nextElement();
	    String[] paramValues = request.getParameterValues(paramName);

	    for (int i = 0; i < paramValues.length; i++)
		paramValues[i] = Encoder.toNewFromOld(paramValues[i], oldEncoding, dtsEncoding);
	}
    }

    /**
     * 请求编码转换，一般使用于POST的URL方式。
     * 
     * @param request HttpServletRequest对象
     * @param oldEncoding 原始编码
     * @param dtsEncoding 新编码
     * @param qs
     * @throws UnsupportedEncodingException
     */
    public static void convertPostUrlEncode(HttpServletRequest request, String oldEncoding, String dtsEncoding, String qs)
	    throws UnsupportedEncodingException {
	Enumeration<?> paramNames = request.getParameterNames();

	while (paramNames.hasMoreElements()) {
	    String paramName = (String) paramNames.nextElement();
	    if (qs.indexOf(paramName + "=") <= -1) continue;
	    String[] paramValues = request.getParameterValues(paramName);

	    for (int i = 0; i < paramValues.length; i++)
		paramValues[i] = Encoder.toNewFromOld(paramValues[i], oldEncoding, dtsEncoding);
	}
    }

    /**
     * 获取当前请求（HttpServletRequest）的完整URL地址。
     * 
     * @return 完整URL地址。
     */
    public static String getFullPath() {
	return getFullPath(getRequest());
    }

    /**
     * 获取指定请求（HttpServletRequest）的完整URL地址。
     * 
     * @param request HttpServletRequest
     * @return 完整URL地址。
     */
    public static String getFullPath(HttpServletRequest r) {
	return r.getScheme() + "://" + r.getServerName() + ":" + r.getServerPort() + r.getContextPath() + "/";
    }

    /**
     * 获取当前请求（HttpServletRequest）的客户端IP地址。
     * 
     * @return IP Address 
     */
    public static String getIpAddress() {
	return getIpAddress(getRequest());
    }

    /**
     * 获取指定请求（HttpServletRequest）的客户端IP地址。
     * 
     * @param request HttpServletRequest
     * @return IP Address 
     */
    public static String getIpAddress(HttpServletRequest request) {
	String ip = request.getHeader("x-forwarded-for");
	if (isIpNotUnknown(ip)) return ip;
	ip = request.getHeader("Proxy-Client-IP");
	if (isIpNotUnknown(ip)) return ip;
	ip = request.getHeader("WL-Proxy-Client-IP");
	if (isIpNotUnknown(ip)) return ip;
	ip = request.getRemoteAddr();
	return ip;
    }

    private static boolean isIpNotUnknown(String ip) {
	return StringUtils.isNotBlank(ip) && !"unknown".equalsIgnoreCase(ip);
    }

    /**
     * 获取传入的request中指定的参数或属性值。
     * 
     * @param request HttpServletRequest
     * @param paramName 名称
     * @return 参数或属性值
     */
    public static Object getValue(HttpServletRequest request, String paramName) {
	Object vo = null;
	if (null != (vo = request.getParameter(paramName))) {
	    return vo;
	}
	if (null != (vo = request.getParameterValues(paramName))) {
	    return vo;
	}
	if (null != (vo = request.getAttribute(paramName))) {
	    return vo;
	}
	return vo;
    }

}
